<?php

namespace app\logic;

/**
 * 微信支付相关
 * Class WeChatPay
 * @package app\mobile\logic
 */
class WeChatPay extends WeChat
{
    private static $obj = null;

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 类入口
     * @return WeChatPay|null
     */
    public static function getInstance()
    {
        if (is_null(self::$obj))
            self::$obj = new self();
        return self::$obj;
    }

    /**
     * 微信公众号支付
     * @param string $str_out_trade_no 商户系统内部订单号
     * @param float $float_order_amount 订单金额 单位元
     * @param string $str_openid openid
     * @return array|bool
     */
    public function weChatPublicNumberPay($str_out_trade_no, $float_order_amount, $str_openid)
    {
        $str_notify_url = config('queue.wechat_public_pay_back_url');
        $arr_data = [
            'appid' => config('wechat.public_number_app_id'), // 微信支付分配的公众账号ID（企业号corpid即为此appId）
            'mch_id' => config('wechat.public_number_mch_id'), // 微信支付分配的商户号
            'nonce_str' => $this->_getRandomString(32), //随机字符串，不长于32位
            'body' => '购买商品', // 商品简单描述，该字段请按照规范传递，
            'out_trade_no' => $str_out_trade_no, // 商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*@ ，且在同一个商户号下唯一。详见商户订单号
            'total_fee' => intval($float_order_amount * 100), // 订单总金额，单位为分，详见支付金额
            'spbill_create_ip' => '139.224.112.17', // APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
            'notify_url' => $str_notify_url, // 异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
            'trade_type' => 'JSAPI', // 取值如下：JSAPI，NATIVE，APP等，说明详见参数规定
            'openid' => $str_openid, // trade_type=JSAPI时（即公众号支付），此参数必传，此参数为微信用户在商户对应appid下的唯一标识。openid如何获取，可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid，再调用【企业号userid转openid接口】进行转换
        ];
        $str_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';

        $arr_sign = $this->weChatSign($arr_data, config('wechat.public_number_pay_key'));
        $arr_result = (array)$this->xmlToArray($this->_curlPost($str_url, $arr_sign['xml']));

        if (isset($arr_result['return_code']) && 'SUCCESS' == $arr_result['return_code'] && isset($arr_result['result_code']) && 'SUCCESS' == $arr_result['result_code']) {
            $arr_pay_info = [
                "appId" => $arr_result['appid'],
                "timeStamp" => strval(time()),
                "nonceStr" => $arr_result['nonce_str'],
                "package" => "prepay_id=" . $arr_result['prepay_id'],
                'signType' => 'MD5',
            ];
            $arr_pay_info['paySign'] = $this->weChatSign($arr_pay_info, config('wechat.public_number_pay_key'))['sign'];
            return $arr_pay_info;

        }
        return false;
    }

    /**
     * 微信APP支付
     * @param $str_out_trade_no
     * @param $float_order_amount
     * @return array|bool
     */
    public function weChatAppPay($str_out_trade_no, $float_order_amount)
    {
        $str_notify_url = config('queue.wechat_app_pay_back_url');
        $arr_data['appid'] = config('wechat.app_app_id'); // 微信开放平台审核通过的应用APPID
        $arr_data['mch_id'] = config('wechat.app_mch_id'); // 微信支付分配的商户号
        $arr_data['device_info'] = 'WEB'; // 终端设备号(门店号或收银设备ID)，默认请传"WEB"
        $arr_data['nonce_str'] = $this->_getRandomString(32); // 随机字符串，不长于32位
        $arr_data['body'] = '购买商品'; // 商品描述交易字段格式根据不同的应用场景按照以下格式：APP——需传入应用市场上的APP名字-实际商品名称，天天爱消除-游戏充值。
        $arr_data['out_trade_no'] = $str_out_trade_no; // 商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
        $arr_data['total_fee'] = $float_order_amount * 100; // 订单总金额，单位为分
        $arr_data['spbill_create_ip'] = '139.224.112.17'; // 用户端实际ip
        $arr_data['notify_url'] = $str_notify_url; // 接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
        $arr_data['trade_type'] = 'APP'; // 支付类型

        $arr_sign = $this->weChatSign($arr_data, config('wechat.app_pay_key'));
        $arr_result = $this->xmlToArray($this->_curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $arr_sign['xml']));
        if ($arr_result['return_code'] == 'SUCCESS' && $arr_result['result_code'] == 'SUCCESS') {
            $arr_pay_info = [
                'appid' => $arr_result['appid'], //应用APPID
                'partnerid' => $arr_result['mch_id'], //商户号
                'noncestr' => $arr_result['nonce_str'], // 随机字符串
                'prepayid' => $arr_result['prepay_id'], // 预支付交易会话标识
                'package' => 'Sign=WXPay', //
                'timestamp' => strval(time()), // 交易时间
            ];
            $arr_pay_info['sign'] = $this->weChatSign($arr_pay_info, config('wechat.app_pay_key'))['sign'];
            return $arr_pay_info;
        } else {
            return false;
        }
    }

    /**
     * 获取微信公众号支付信息(返回给前端的数据)
     * @param $str_app_id
     * @param $str_nonce_str
     * @param $str_prepay_id
     * @return array
     */
    public function getWeChatPublicNumberPayInfo($str_app_id, $str_nonce_str, $str_prepay_id)
    {
        $arr_pay_info = [
            "appId" => $str_app_id,
            "timeStamp" => strval(time()),
            "nonceStr" => $str_nonce_str,
            "package" => "prepay_id=" . $str_prepay_id,
            'signType' => 'MD5',
        ];

        $arr_pay_info['paySign'] = $this->weChatSign($arr_pay_info, config('wechat.public_number_pay_key'))['sign'];
        return $arr_pay_info;
    }
}
